import { ShallowRef, Ref, shallowRef, onBeforeUnmount } from "vue";
import * as echarts from "echarts";
import { ECharts, EChartsCoreOption } from "echarts/core";
import { ChartType } from "./type";
import * as ChartConfig from "./config";
import mapJson from "./data/config";
import "echarts-gl";
import axios from "axios";

interface ChartHookOption {
  type?: any;
  svgMapUrl?: any;
  timeLoad?: boolean;
  // type?: Ref<ChartType>;
  el: ShallowRef<HTMLElement>;
  mapName?: string;
}

/* 获取缩放比例全屏
 * @param {boolean} containRatio 是否计算设备像素比
 * @param {number | string} baseWidth 基础宽度
 */
export const getScale = (containRatio = true, baseWidth = 1920) => {
  const currentScale = document.documentElement.clientWidth / baseWidth;
  const formattedScale = currentScale > 1 ? currentScale : 1;
  const resultScale = containRatio
    ? formattedScale * window.devicePixelRatio
    : formattedScale;
  return Math.ceil(resultScale);
};

/**
 *  视口变化时echart图表自适应调整
 */
class ChartsResize {
  #charts = new Set<ECharts>(); // 缓存已经创建的图表实例
  #timeId = null;
  constructor() {
    window.addEventListener("resize", this.handleResize.bind(this)); // 视口变化时调整图表
  }
  getCharts() {
    return [...this.#charts];
  }
  handleResize() {
    clearTimeout(this.#timeId);
    this.#timeId = setTimeout(() => {
      this.#charts.forEach((chart) => {
        chart.resize();
      });
    }, 500);
  }
  add(chart: ECharts) {
    this.#charts.add(chart);
  }
  remove(chart: ECharts) {
    this.#charts.delete(chart);
  }
  removeListener() {
    window.removeEventListener("resize", this.handleResize);
  }
}

export const chartsResize = new ChartsResize();

export const useCharts = ({
  type,
  timeLoad,
  svgMapUrl,
  el,
  mapName,
}: ChartHookOption) => {
  const charts = shallowRef();
  let options!: EChartsCoreOption;
  let initComplete = false;

  const setOptions = (opt: EChartsCoreOption) => {
    initComplete && charts.value.setOption(opt);
  };

  const fetchMapData = async (mapname, url) => {
    return new Promise((resolve) => {
      axios({
        method: "get",
        url: url,
        responseType: "stream",
      }).then((response) => {
        echarts.registerMap(mapname, { svg: response.data });
        resolve("ok");
      });
    });
  };

  const initChart = async (defaultOptions) => {
    if (mapName?.includes("svg")) {
      await fetchMapData(mapName, svgMapUrl);
    } else if (mapName) {
      mapName.split(",").map(async (item) => {
        if (item.includes("svg")) {
        } else {
          echarts.registerMap(item, mapJson[item]);
        }
      });
    }
    charts.value = echarts.init(el.value, null, {
      devicePixelRatio: getScale(),
    });
    if (ChartConfig[type.value]) {
      options = ChartConfig[type.value](defaultOptions, charts.value);
    } else {
      options = defaultOptions;
    }
    charts.value.setOption(options);
    if (type.value === "Pie3d") {
      setTimeout(() => {
        ChartConfig.bindListen(charts.value, options);
      }, 1000);
    }
    if (timeLoad)
      SetTimeLoad(charts.value, options.dataset, options.series, options);
    chartsResize.add(charts.value); // 将图表实例添加到缓存中
    initComplete = true;
    chartsResize.handleResize();
    // 初始化高亮 默认第一个
    charts.value.dispatchAction({
      type: "highlight",
      seriesIndex: 0,
      dataIndex: 0,
    });
  };

  let interVal = null;
  let currentIndex = -2;
  const SetTimeLoad = (myChart, dataset, series, options) => {
    interVal = setInterval(() => {
      const dataArr = dataset ? dataset.source : series[0].data || [];
      let dataLen = dataArr.length;

      if (options.dataZoom) {
        if (Number(options.dataZoom[0].endValue) === dataLen) {
          options.dataZoom[0].endValue = 6;
          options.dataZoom[0].startValue = 0;
        } else {
          options.dataZoom[0].endValue = options.dataZoom[0].endValue + 1;
          options.dataZoom[0].startValue = options.dataZoom[0].startValue + 1;
        }
        charts.value.setOption(options);
      }

      // 取消之前高亮的图形
      myChart.dispatchAction({
        type: "downplay",
        seriesIndex: [0, 1],
        dataIndex: currentIndex,
      });
      currentIndex = (currentIndex + 1) % dataLen;
      // 高亮当前图形
      myChart.dispatchAction({
        type: "highlight",
        seriesIndex: [0, 1],
        dataIndex: currentIndex,
      });

      // if (series[0].data && series.length > 1) {
      //   // 显示 tooltip
      //   myChart.dispatchAction({
      //     type: "showTip",
      //     seriesIndex: 0,
      //     dataIndex: currentIndex,
      //   });
      // } else {
      //   // 显示 tooltip
      //   myChart.dispatchAction({
      //     type: "showTip",
      //     seriesIndex: series.length == 1 ? 0 : 1,
      //     dataIndex: currentIndex,
      //   });
      // }
      // 显示 tooltip
      myChart.dispatchAction({
        type: "showTip",
        seriesIndex: series.length == 1 ? 0 : 1,
        dataIndex: currentIndex,
        confine: true,
        // appendToBody: true,
      });
    }, 2000);
  };

  onBeforeUnmount(() => {
    chartsResize.remove(charts.value); // 移除缓存
    clearInterval(interVal);
    interVal = null;
  });

  return {
    charts,
    initChart,
    setOptions,
  };
};

export * from "./type.d";
